package com.thinkgem.jeesite.test;
import com.thinkgem.jeesite.common.utils.StringUtils;
/**
* Description:
*
*
*
*
* @Author: leo.xiong
* @CreateDate: 2023/3/2 16:32
* @Email: [email protected]
* @Since:
*/
public class BitTest {
public static void main(String[] args) {
System.out.println("1、计算机存储的最小单位是 bit(位,只有0和1);");
System.out.println("2、一个byte 可以表示 0-255的数字 255=2^7-1,所以需要8位,short 2个byte16位,int 4个byte 32位,long 8个byte 64位;");
System.out.println("3、高低字节:左边的是低字节,右边的是高字节;");
System.out.println("4、高低地址:bytes数组的索引最小的是最低地址,索引最大的为最高地址;");
System.out.println("5、大端存储,低地址->高字节|高地址->低字节:一个short 2个byte:byte[0]=右边的byte byte[1]=左边的byte");
System.out.println("6、小端存储,低地址->低字节|高地址->高字节:一个short 2个byte:byte[0]=左边的byte byte[1]=右边的byte");
System.out.println("7、一个short拆分2个byte,拆分成2个8位就是2个byte");
System.out.println("8、value & 0xFF 0XFF的二进制位11111111 8位的1,做位运算就表示只截取8位一个byte,保留原数据后8为的二进制");
System.out.println("9、定义一个大于255的数字,又小于 2^15-1=32767的数字 355 00000001 01100011 = 2^8+2^6+2^5+2^1+2^0=256+64+32+2+1=355");
System.out.println("10、大端,参照第5点");
System.out.println("Byte是有符号的:" + toBinary(new byte[]{Byte.MAX_VALUE})
+ ">>>>>" + toBinary(new byte[]{(byte) 0XFF})
+ ">>>>>" + toBinary(new byte[]{Byte.MAX_VALUE | Byte.MIN_VALUE})
+ "\n>>>>>" + "数字对0XFF做 & 运算,就是保留最后面的8位二进制,但需要注意首位为1,表示负数,所以原始数据为正数,需要考虑符号问题,还原时需要进行无符号计算"
+ "\n>>>>>" + "实现方式,可以理解为用一个更大的值装byte,比如Short,int,long,之后对后面的8位个OXFF做位运算,这样就保留了前面的值,第8为的符号位就不是第一位了"
+ "\n>>>>>" + "Byte为负数,需要进行无符号转换"
+ "\n>>>>>" + ((int) ((byte) 128) & 0XFF)
+ ">>>>>" + Byte.toUnsignedLong((byte) 0XFF));
short a = 355;
shortToBytes(a);
int b = 132767;
intToBytes(b);
long c = Long.MAX_VALUE - 11112560;
longToBytes(c);
System.out.println("12、可以看出,JAVA的API默认是大端存储");
System.out.println("13、解析原理第一步 byte & 11111111转为二进制,之后根据前面存储把它移动到指定位置,注意数据大小,使用不同的类型存储,最后所有的数据做或(|)运算就是结果集");
}
private static byte[] shortToBytes(short a) {
System.out.println(" 原始值:" + a);
System.out.println("API short:" + printBinaryString(StringUtils.leftPad(Integer.toBinaryString(a), 16, '0')));
//用2个byte存储short,存储参照第5点
byte[] bytes = new byte[2];
//高字节位的byte 0XFF
bytes[0] = (byte) (a & 0XFF);
//向右移动8位去掉后面一个byte,这样留下来的就是左边的byte,在做位运算
bytes[1] = (byte) (a >> 8 & 0XFF);
System.out.println(" 大端:" + BitTest.toBinary(reverseBytes(bytes)));
System.out.println(" 小端:" + BitTest.toBinary(bytes));
System.out.println("大端还原:" + bytesToShort(bytes, true));
System.out.println("小端还原:" + bytesToShort(reverseBytes(bytes), false));
// //用2个byte存储short,存储参照第5点
// bytes = new byte[2];
// //低字节位的byte
// bytes[0] = (byte) (a >> 8 & 0XFF);
// //向右移动8位去掉后面一个byte,这样留下来的就是左边的byte,在做位运算
// bytes[1] = (byte) (a & 0XFF);
// System.out.println(" 小端:" + BitTest.toBinary(new byte[]{bytes[1], bytes[0]}));
return bytes;
}
/**
* byte转short,就需要考虑是大小端存储否则数据不同
*
* @param bytes
* @param isBigEndian 是否大端
* @return
*/
private static short bytesToShort(byte[] bytes, boolean isBigEndian) {
short value = 0;
for (int i = 0, len = bytes.length; i
value |= (short) (bytes[i] & 0XFF)
System.out.println(" 原始值:" + b);
System.out.println("API int:" + printBinaryString(StringUtils.leftPad(Integer.toBinaryString(b), 32, '0')));
byte[] bytes = new byte[4];
bytes[0] = (byte) (b & 0XFF);
bytes[1] = (byte) (b >> 8 & 0XFF);
bytes[2] = (byte) (b >> 16 & 0XFF);
bytes[3] = (byte) (b >> 24 & 0XFF);
System.out.println(" 大端:" + BitTest.toBinary(reverseBytes(bytes)));
System.out.println(" 小端:" + BitTest.toBinary(bytes));
System.out.println("大端还原:" + bytesToInt(bytes, true));
System.out.println("小端还原:" + bytesToInt(reverseBytes(bytes), false));
return bytes;
}
/**
* byte转int,就需要考虑是大小端存储否则数据不同
*
* @param bytes
* @param isBigEndian 是否大端
* @return
*/
private static int bytesToInt(byte[] bytes, boolean isBigEndian) {
int value = 0;
for (int i = 0, len = bytes.length; i
value |= (bytes[i] & 0XFF)
System.out.println(" 原始值:" + Long.valueOf(c));
System.out.println("API long:" + printBinaryString(StringUtils.leftPad(Long.toBinaryString(c), 64, '0')));
byte[] bytes = new byte[8];
bytes[0] = (byte) (c & 0XFF);
bytes[1] = (byte) (c >> 8 & 0XFF);
bytes[2] = (byte) (c >> 16 & 0XFF);
bytes[3] = (byte) (c >> 24 & 0XFF);
bytes[4] = (byte) (c >> 32 & 0XFF);
bytes[5] = (byte) (c >> 40 & 0XFF);
bytes[6] = (byte) (c >> 48 & 0XFF);
bytes[7] = (byte) (c >> 56 & 0XFF);
System.out.println(" 大端:" + BitTest.toBinary(reverseBytes(bytes)));
System.out.println(" 小端:" + BitTest.toBinary(bytes));
System.out.println("大端还原:" + bytesToLong(bytes, true));
System.out.println("小端还原:" + bytesToLong(reverseBytes(bytes), false));
return bytes;
}
/**
* @param bytes
* @param isBigEndian 是否大端
* @return
*/
private static long bytesToLong(byte[] bytes, boolean isBigEndian) {
long value = 0L;
for (int i = 0, len = bytes.length; i
value |= (long) (bytes[i] & 0XFF)
byte[] newBytes = new byte[bytes.length];
for (int i = 0, len = bytes.length; i
StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE + bytes.length - 1);
for (int i = 0; i
sb.append(" ");
}
sb.append((bytes[i / Byte.SIZE]
for (int j = 0; j |